package com.example.portablefortheelderlybackground.config.Exception;

import com.example.portablefortheelderlybackground.config.Exception.user.TokenInvalidationException;
import com.example.portablefortheelderlybackground.utils.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.net.BindException;
import java.util.stream.Collectors;

import static com.example.portablefortheelderlybackground.Enum.Message.ReturnMessageEnum.TOKEN_INVALIDATION;

/**
 * @author 86187
 * @description: 全局异常处理类
 * @date: 2023/7/5 11:14
 */

@RestControllerAdvice
@Slf4j
public class GlobalException {

    //*******************   空指针的全局异常处理   *******************//
    @ExceptionHandler({NullPointerException.class})
    public Response<String> NullPointerExceptionHandler(NullPointerException exception) {
        log.error("空指针异常");
        return Response.error("服务繁忙,请稍后再试");
    }

    //*******************   token失效的全局异常处理   *******************//
    @ExceptionHandler({TokenInvalidationException.class})
    public Response<String> TokenInvalidationExceptionHandler(TokenInvalidationException invalidationException) {
        return Response.error(invalidationException.getMessage(), TOKEN_INVALIDATION.getCode(), TOKEN_INVALIDATION.getMessage());
    }

    //*******************   处理参数校验的异常处理   *******************//
    @ExceptionHandler(value = {MethodArgumentNotValidException.class, ValidationException.class, BindException.class})
    public Response<String> validationException(Exception exception) {
        log.info("参数校验失败!");
        if (exception instanceof MethodArgumentNotValidException methodArgumentNotValidException) {
            return Response.error(methodArgumentNotValidException.getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining("; ")), "数据校验失败");
        } else if (exception instanceof ConstraintViolationException constraintViolationException) {
            return Response.error(constraintViolationException.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining("; ")), "数据效验失败");
        } else if (exception instanceof BindException bindException) {
            return Response.error(bindException.getMessage(), "数据效验失败");
        }
        return Response.error(exception.getMessage(), "数据效验失败");
    }
}
